package net.wicp.tams.plugin.task;

import java.io.File;
import java.io.IOException;
import java.util.Properties;

import org.apache.commons.io.FileUtils;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;

import net.wicp.tams.common.Conf;
import net.wicp.tams.common.Result;
import net.wicp.tams.common.apiext.IOUtil;
import net.wicp.tams.common.apiext.StringUtil;
import net.wicp.tams.common.apiext.TarUtil;
import net.wicp.tams.common.constant.BasePath;
import net.wicp.tams.common.constant.Env;
import net.wicp.tams.common.exception.ProjectException;
import net.wicp.tams.common.os.SSHAssit;
import net.wicp.tams.common.os.pool.SSHConnection;

/****
 * 
 * @author zhoujunhui
 *
 */
@Mojo(name = "dkconf", requiresProject = true, threadSafe = true)
public class DuckulaConf extends AbstractMojo {
	/***
	 * 原始密码
	 */
	@Parameter(property = "env", required = false)
	private Env env;

	@Parameter(defaultValue = "${basedir}", required = true)
	private String basedir;

	@Parameter(required = true)
	private String[] plugs;

	@Parameter(required = true)
	private String[] serializers;

	@Parameter(required = true)
	private String[] busis;

	@Parameter(required = false)
	private boolean isall;// 是否要打包 data数据

	@Parameter(required = false)
	private boolean isDocker;// 是否要打docker镜像
	@Parameter(required = false)
	private boolean needpush;// 是否需要推镜像仓库

	@Parameter(required = false)
	private String tagversion;// tag的版本，如果没有传则用项目的版本

	@Parameter(required = false)
	private String rootPwd;// root用户密码,打docker镜像时需要登陆

	@Parameter(defaultValue = "${project}")
	private MavenProject project;

	@Override
	public void execute() throws MojoExecutionException, MojoFailureException {
		BasePath.projectBasePath = basedir;
		if (isall) {
			getLog().info("------------------------增加接收插件---------------------");
			String pluginDirPath = String.format("%s/target/duckula-data/sender", basedir);// 不用 /plugins/
																							// ，否则有文件elasticsearch-rest-client-sniffer-6.3.2.jar名字超过100字符
			File pluginDir = new File(pluginDirPath);
			pluginDir.deleteOnExit();

			installPlugs(pluginDirPath, plugs);
			getLog().info("------------------------增加序列化插件---------------------");
			// 序列化插件
			String serializerDirPath = String.format("%s/target/duckula-data/serializer", basedir);
			File serializerDir = new File(serializerDirPath);
			serializerDir.deleteOnExit();
			installPlugs(serializerDirPath, serializers);

			getLog().info("------------------------增加业务定制插件---------------------");
			String busiDirPath = String.format("%s/target/duckula-data/busi", basedir);
			File busiDir = new File(busiDirPath);
			busiDir.deleteOnExit();
			installPlugs(busiDirPath, busis);
			getLog().info("------------------------增加binlog目录---------------------");
			String binlogDirPath = String.format("%s/target/duckula-data/binlog", basedir);
			File binlogDir = new File(binlogDirPath);
			try {
				// binlogDir.deleteOnExit();
				FileUtils.forceMkdir(binlogDir);
			} catch (IOException e) {
				getLog().info("------------------------创建binlogDir目录失败---------------------");
			}
			getLog().info("------------------------增加pos位点更新日志---------------------");
			String posDirPath = String.format("%s/target/duckula-data/pos", basedir);
			File posDir = new File(posDirPath);
			try {
				// posDir.deleteOnExit();会导致创建目录不成功
				FileUtils.forceMkdir(posDir);
			} catch (IOException e) {
				getLog().info("------------------------创建posDir目录失败---------------------");
			}
			getLog().info("------------------------增加consumer插件目录---------------------");
			String consumerDirPath = String.format("%s/target/duckula-data/consumers", basedir);
			File consumerDir = new File(consumerDirPath);
			try {
				FileUtils.forceMkdir(consumerDir);
			} catch (IOException e) {
				getLog().info("------------------------创建consumer插件目录失败---------------------");
			}
		}

		getLog().info("------------------------bin---------------------");
		File targetBinDir = new File(String.format("%s/target/duckula/bin", basedir));
		File binDir = new File(String.format("%s/bin/", basedir));
		try {
			FileUtils.copyDirectory(binDir, targetBinDir);
		} catch (IOException e) {
			getLog().info("bin复制错误", e);
		}

		if (isall) {
			getLog().info("------------------------conf(打docker时必须要放到duckula-data)--------------------------");
			File targetConfDir = new File(String.format("%s/target/duckula-data/conf", basedir));
			env = env == null ? Env.dev : env;// 配置分环境
			File confDir = new File(String.format("%s/conf-%s/", basedir, env.name()));
			try {
				FileUtils.copyDirectory(confDir, targetConfDir);
			} catch (IOException e) {
				getLog().info("conf复制错误", e);
			}
			getLog().info("------------------------logs文件复制---------------------");
			File logsDir = new File(String.format("%s/logs/", basedir));
			File targetLogsDir = new File(String.format("%s/target/duckula-data/logs", basedir));
			try {
				FileUtils.copyDirectory(logsDir, targetLogsDir);
			} catch (IOException e) {
				getLog().info("logsDir复制错误", e);
			}
			
			getLog().info("------------------------k8s的文件复制---------------------");
			File k8sDir = new File(String.format("%s/k8s/", basedir));
			File targetK8sDir = new File(String.format("%s/target/duckula-data/k8s", basedir));
			try {
				FileUtils.copyDirectory(k8sDir, targetK8sDir);
			} catch (IOException e) {
				getLog().info("k8sDir复制错误", e);
			}
		}

		getLog().info("------------------------task复制---------------------");
		String taskBasePath = String.format("%s/../%s/target/", basedir, "duckula-task");
		File taskJarFile = new File(taskBasePath + "duckula-task.jar");
		File taskLibDir = new File(taskBasePath + "lib");
		File targetDir = new File(String.format("%s/target/duckula/", basedir));
		try {
			FileUtils.copyFile(taskJarFile, new File(targetDir, "duckula-task.jar"));
			FileUtils.copyDirectory(taskLibDir, new File(targetDir, "lib"));
		} catch (IOException e) {
			getLog().info("复制task项目错误", e);
		}

		getLog().info("------------------------dump复制---------------------");
		String dumpBasePath = String.format("%s/../%s/target/", basedir, "duckula-dump-elasticsearch");
		File dumpJarFile = new File(dumpBasePath + "duckula-dump-elasticsearch.jar");
		File dumpLibDir = new File(dumpBasePath + "lib-dump");
		try {
			FileUtils.copyFile(dumpJarFile, new File(targetDir, "duckula-dump-elasticsearch.jar"));
			FileUtils.copyDirectory(dumpLibDir, new File(targetDir, "lib-dump"));
		} catch (IOException e) {
			getLog().info("复制dump项目错误", e);
		}

		getLog().info("------------------------consumer复制---------------------");
		String consumerBasePath = String.format("%s/../%s/target/", basedir, "duckula-kafka-consumer");
		File consumerJarFile = new File(consumerBasePath + "duckula-kafka-consumer.jar");
		File consumerLibDir = new File(consumerBasePath + "lib-consumer");
		try {
			FileUtils.copyFile(consumerJarFile, new File(targetDir, "duckula-kafka-consumer.jar"));
			FileUtils.copyDirectory(consumerLibDir, new File(targetDir, "lib-consumer"));
		} catch (IOException e) {
			getLog().info("复制consumer项目错误", e);
		}
		getLog().info("------------------------打tar包---------------------");
		TarUtil.compress(targetDir, targetDir.getPath() + ".tar");// duckula.tar

		if (isall) {
			getLog().info("------------------------打data包---------------------");
			File data = new File(String.format("%s/target/duckula-data/", basedir));
			TarUtil.compress(data, data.getPath() + ".tar");// duckula-data.tar
		}

		getLog().info("------------------------进行docker文件处理(需要操作系统安装docker)---------------------");
		getLog().info("------------------------dockerfile文件复制---------------------");
		File dockerConfDir = new File(String.format("%s/target", basedir));
		File dockerDir = new File(String.format("%s/docker/", basedir));
		try {
			FileUtils.copyDirectory(dockerDir, dockerConfDir);
		} catch (IOException e) {
			getLog().info("dockerfile复制错误", e);
		}
		
		
		
		

		if (isDocker && isall) {// isall为true才能打镜像
			getLog().info("------------------------docker and k8s---------------------");
			Properties props = new Properties();
			props.put("common.os.ssh.cmd.timeout", 1000 *60*20);// 给5分钟打docker,加上push需要10分种
			Conf.overProp(props);
			SSHConnection conn;
			try {
				conn = SSHAssit.getConn("127.0.0.1", 22, "root", rootPwd);
			} catch (ProjectException e) {
				throw new MojoFailureException("ssh 失败", e);
			}
			Result chmodRes = conn.executeCommand(
					"chmod +x " + IOUtil.mergeFolderAndFilePath(basedir, "/target/duckula/bin/docker-build.sh"));
			if (!chmodRes.isSuc()) {
				throw new MojoFailureException("修改权限失败：" + chmodRes.getMessage());
			}
			String cmdstr = String.format("%s %s %s",
					IOUtil.mergeFolderAndFilePath(basedir, "/target/duckula/bin/docker-build.sh"),
					IOUtil.mergeFolderAndFilePath(basedir, "/target"),
					StringUtil.isNull(tagversion) ? project.getVersion() : tagversion);
			if (needpush) {// 推送镜像库
				cmdstr = cmdstr + " true";
			}
			getLog().info("------------------------开始打docker镜像，需要一些时间，请耐心等待---------------------");
			Result dockerBuildRes = conn.executeCommand(cmdstr);
			if (!dockerBuildRes.isSuc()) {
				throw new MojoFailureException("执行docker-build失败：" + dockerBuildRes.getMessage());
			}
		}

		getLog().info("------------------------dkconf完成---------------------");
	}

	private void installPlugs(String pluginDirPath, String[] plugNames) throws MojoFailureException {
		for (String plugName : plugNames) {
			try {
				File srcFile = new File(String.format("%s/../%s/target/%s.jar", basedir, plugName, plugName));
				File targetFile = new File(String.format("%s/%s/%s.jar", pluginDirPath, plugName, plugName));
				FileUtils.copyFile(srcFile, targetFile);
				File libDir = new File(String.format("%s/../%s/target/lib", basedir, plugName));
				File targetLib = new File(String.format("%s/%s", pluginDirPath, plugName));
				FileUtils.copyDirectoryToDirectory(libDir, targetLib);
			} catch (IOException e) {
				throw new MojoFailureException("复制插件有问题", e);
			}
		}
	}

}
